package queue;

import Task.Task;
import Task.ITaskHandle;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.*;

/**
 * 环形队列处理消息延迟问题
 * @version 1.0
 * @author bug-fsh
 */
public class CircularQueue {

    //秒级定时器
    private int time;
    //环形队列容量
    private int circularQueueNum;
    //当前环形队列指针
    private int currentIndex;
    //环形队列容器
    private Set<Task> [] queue;
    //任务map
    private Map<Integer, Integer> map = new HashMap<Integer, Integer>();

    public CircularQueue(int time, int circularQueueNum) {
        this.time = time;
        this.circularQueueNum = circularQueueNum;
        this.queue = new HashSet[circularQueueNum];
    }

    /**
     * 添加任务
     * @param task
     */
    public void addTask(Task task) {
        if (task == null) return;
        int taskIndex = currentIndex - 1 < 0 ? circularQueueNum - 1: currentIndex - 1;
        System.out.println("添加任务索引"+taskIndex);
        if (map.containsKey(task.getId())) {
            int tempTaskIndex = map.get(task.getId());
            map.remove(task.getId());
            map.put(task.getId(), taskIndex);
            queue[taskIndex].remove(task);
        }
        if (queue[taskIndex] == null) {
            queue[taskIndex] = new HashSet<Task>();
        }
        queue[taskIndex].add(task);
    }

    /**
     * 执行定时器
     */
    public void excute() throws InterruptedException {
        if (currentIndex >= circularQueueNum) currentIndex = 0;
        System.out.println("处理任务当前索引"+currentIndex);
        if (queue[currentIndex] != null) {
            Set<Task> set = queue[currentIndex];
            Iterator<Task> iterator = set.iterator();
            while (iterator.hasNext()) {
                Task task = iterator.next();
                task.handle();
                iterator.remove();
            }
        }
        currentIndex += 1;
        //Thread.sleep(time * 1000);
    }

    public static void main(String [] args) {
        String str = "我是中国人";
        byte [] bytes = str.getBytes(Charset.forName("gbk"));
        try {
            String string = new String(bytes, "utf-8");
            String string1 = new String(bytes, "gbk");
            System.out.println(string);
            System.out.println(string1


            );
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

class Consumer implements Runnable {
    CircularQueue circularQueue;

    public Consumer(CircularQueue circularQueue) {
        this.circularQueue = circularQueue;
    }

    @Override
    public void run() {
        while (true) {
            try {
                circularQueue.excute();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Producer implements Runnable {
    CircularQueue circularQueue;

    public Producer(CircularQueue circularQueue) {
        this.circularQueue = circularQueue;
    }

    @Override
    public void run() {
        int id = 1;
        while (true) {
            System.out.println(new Date());
            for (int i = 1; i < 10; i++) {
                circularQueue.addTask(new Task(id, new Order(id, "订单"+id), new OrderTaskHandle()));
                ++id;
            }
            try {
                circularQueue.excute();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class OrderTaskHandle  implements ITaskHandle {
    @Override
    public void handle(Task task) {
        System.out.println("执行处理"+task.getData().toString());
    }
}

class Order {
    private int id;
    private String name;
    private long currentTime = new Date().getTime();

    public Order(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", currentTime=" + new Date(currentTime) +
                '}';
    }
}
